架構:
(1) userComponent:
訂閱(subscribe)sharedService 的 User資料
(2)sharedService
利用Subject接收其他componenttj傳來的User資料。
問題:
userComponent 放在一個dialog裡面,預期每次開啟dialog,
都會從sharedService取當下選取到的User,後續接著打一些api。
constructor(private service: SharedService) { }
ngOnInit() {
this.service.getCurrentUser().subscribe(
user => console.log(user)
);
}
但在每一次重新開啟dialog時,會連曾選取過的user一起帶出來 。
如:
第一次點選 : Peter >> Peter
第二次點選 : Winston >> Peter , Winston
第三次點選 : Rossi >> Rossi , Peter , Winston
造成後續打api重複觸發。
解決
因為 subscibe 並不會因為 dialog 關閉就取消訂閱,以至於每次開啟dialog都會發起一個新的訂閱,
需要手動unsubscirbe 或使用 async pipe。
subscription = new Subscription();
constructor(private service: SharedService) { }
ngOnInit() {
this.subscription.add(
this.service.getCurrentUser()
.pipe(
// my api.......
).subscribe(result => console.log(result))
);
}
ngOnDestroy(): void {
console.log('ngOnDestroy');
this.subscription.unsubscribe();
}
宣告一個 Subscriptionsubscription = new Subscription();
將Subscribe 加到 Subscription 中
this.subscription.add(
this.service.getCurrentUser()
.pipe(
switchMap((user: User) => this.service.getDivision(user.ID))
).subscribe(division => this.division = division)
);
在 Dialog 關閉 ngOnDestroy 取消訂閱
ngOnDestroy(): void {
console.log('ngOnDestroy');
this.subscription.unsubscribe();
}
email$: Observable<string>;
constructor(private service: SharedService) { }
ngOnInit(): void {
this.email$ = this.service.getCurrentUser()
.pipe(
switchMap((user: User) => this.service.getEmail(user.ID))
);
}
宣告回傳的 Observable<string>
email$: Observable<string>;
html 使用 async pipe
<ng-container *ngIf="email$ | async as email">
<li class="list-group-item">{{email}}</li>
</ng-container>
async pipe 在component 結束後便會取消訂閱